package com.sinodata.bsm.cicp.collector.common;

/*

 * 两个属性:"采集命令", "条件正则表达式"
 * 四个指标:"用户名","IP地址","登陆时间","登陆状态"
 *
 * */
import java.io.BufferedReader;
import java.io.IOException;
import java.io.Serializable;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.log4j.Logger;

import com.sinodata.bsm.cicp.collector.Collector;
import com.sinodata.bsm.cicp.exception.CollectorException;
import com.sinodata.bsm.cicp.util.CollectorUtil;
import com.sinodata.bsm.common.vo.ResPropertyValue;

/**
 * 
 * <p>
 * Description: 通过last -20命令，得到用户登陆历史，取从上一次采集时间到这次采集时间之间得用户登陆历史值。
 * </p>
 *
 * @author liulibo
 * @version 1.0

 * <p>
 * History: 
 *
 * Date                     Author         Version     Description
 * ---------------------------------------------------------------------------------
 * 2012-12-20 15:36:45      liulibo        1.0         To create
 * </p>
 *
 * @since 
 * @see
 */
public class UserLoginLog extends Collector {

    private static final Logger logger = Logger.getLogger(UserLoginLog.class);

    private static Map<String, String> monthMap = new HashMap<String, String>();

    private static Pattern[] pattern;

    public UserLoginLog() {
    }

    public void init(String[] shell, String[] passMatch) throws Exception {
        //PatternCompiler compiler = new Perl5Compiler();
        String[] m = new String[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
        String[] mn = new String[] { "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12" };
        for (int i = 0; i < m.length; i++) {
            monthMap.put(m[i], mn[i]);
        }
        pattern = new Pattern[passMatch.length];
        for (int i = 0; i < passMatch.length; i++) {
            pattern[i] = Pattern.compile(passMatch[i]);
        }
    }

    @Override
    public List<ResPropertyValue> collect(String ip) throws CollectorException {
        List<ResPropertyValue> values = new ArrayList<ResPropertyValue>();
        ResPropertyValue propertyValueX = null;
        String[] propMetas = getPropMeta();
        ResPropertyValue.PropValue[] propValues = null;
        BufferedReader reader = null;
        String[] shell = this.paramMap.get("采集命令").split(",");
        String[] passMatch = this.paramMap.get("正则表达式").split(",");
        String datetime = "";
        boolean flag = true;
        try {
            init(shell, passMatch);
        } catch (Exception ex) {
            logger.error("failed to init", ex);
        }
        try {
            String hostDateStr = null;
            // PatternMatcher matcher = new Perl5Matcher();
            Matcher matcher = null;
            reader = CollectorUtil.getReader(shell[0], ip);
            String line = null;
            while ((line = reader.readLine()) != null) {
                line = line.trim();
                /*if (matcher.contains(line, pattern[0])) {
                    hostDateStr = matcher.getMatch().group(1);

                }*/
                matcher = pattern[0].matcher(line);
                if (matcher.find()) {
                    hostDateStr = matcher.group(1);
                }
            }
            String colltime = null;
            Serializable temp = this.getPersistentData(ip);
            if (temp != null) {
                colltime = temp.toString();
            }
            reader = CollectorUtil.getReader(shell[1], ip);
            while ((line = reader.readLine()) != null) {
                line = line.trim();
                /* if (matcher.contains(line, pattern[1])) {
                     String userName = matcher.getMatch().group(1);
                     String userIp = matcher.getMatch().group(2);
                     String month = matcher.getMatch().group(3);
                     String days = matcher.getMatch().group(4);
                     String times = matcher.getMatch().group(5);
                     String state = matcher.getMatch().group(6);*/
                matcher = pattern[1].matcher(line);
                if (matcher.find()) {
                    String userName = matcher.group(1);
                    String userIp = matcher.group(2);
                    String month = matcher.group(3);
                    String days = matcher.group(4);
                    String times = matcher.group(5);
                    String state = matcher.group(6);
                    datetime = getDateStr(hostDateStr.substring(0, 4), month, days) + " " + times;
                    if (flag) {
                        try {
                            this.savePersistentData(ip, datetime);
                        } catch (IOException e) {
                            //								System.out.println(e);
                        }
                        flag = false;
                    }
                    if (colltime == null || getMills(datetime, colltime) > 0) {
                        //sb记录日志在IF里面在满足条件下加入。
                        propertyValueX = new ResPropertyValue();
                        propValues = new ResPropertyValue.PropValue[propMetas.length];
                        propValues[0] = ResPropertyValue.createPropValue(userName, propMetas[0]);
                        propValues[1] = ResPropertyValue.createPropValue(userIp, propMetas[1]);
                        propValues[2] = ResPropertyValue.createPropValue(month + days + times, propMetas[2]);
                        propValues[3] = ResPropertyValue.createPropValue(state, propMetas[3]);
                        propertyValueX.setValues(propValues);
                        values.add(propertyValueX);
                    }
                }
            }
        } catch (Exception ex) {
            logger.error("failed to collect sulog info", ex);
            throw new CollectorException(ex);
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException ex1) {
                    logger.error("failed to close  BufferedReader", ex1);
                }
            }
        }
        return values;
    }

    @Override
    public String[] getParamMeta() {
        return new String[] { "采集命令", "条件正则表达式" };
    }

    @Override
    public String[] getPropMeta() {
        return new String[] { "用户名", "IP地址", "登陆时间", "登陆状态" };
    }

    /*
     * 获得两个日期相差的毫秒数
     */
    private static long getMills(String endTime, String startTime) throws CollectorException {
        long quot = 0;
        SimpleDateFormat ft = new SimpleDateFormat("yyyy/MM/dd HH:mm");
        if (endTime == null) {
            endTime = ft.format(new Date());
        }
        try {
            Date date1 = ft.parse(endTime);
            Date date2 = ft.parse(startTime);
            quot = date1.getTime() - date2.getTime();
        } catch (ParseException e) {
            logger.error("failed to get time mills", e);
            throw new CollectorException(e);
        }
        return quot;
    }

    private static String getDateStr(String year, String month, String days) {
        return year + "/" + monthMap.get(month) + "/" + (days.length() == 2 ? days : "0" + days);
    }

    public static void main(String[] args) {
        //        UserLoginLog collector = new UserLoginLog();
        //        collector.setInterval(10);
        //        Map paramMap = new HashedMap();
        //        paramMap.put("采集命令", "date +'A%Y/%m/%d %H:%MA', last -20");
        //        //		paramMap.put("正则表达式", "A(.*)A,(\\S+)\\s+\\S+\\s+(\\S+)\\s+(\\w+)\\s+(\\d+)\\s+(\\S+)\\s+-?(.*)");  aix 正则表达式
        //        paramMap.put("正则表达式", "A(.*)A,(\\w+)\\s+\\S+\\s+(\\d+\\.\\d+\\.\\d+\\.\\d+)\\s+\\w+\\s+(\\w+)\\s+(\\d+)\\s+(\\S+)\\s+-?(.*)");//linux 正则表达式
        //        collector.setParamMap(paramMap);
        //        List<ResPropertyValueX> list = collector.collect("192.168.0.128");
        //        for (int i = 0; i < list.size(); i++) {
        //            System.out.println(list.get(i).toString());
        //        }
    }
}
